package com.csun.dsms.controller;

import com.csun.dsms.comment.base.enums.ErrorCodeEnum;
import com.csun.dsms.comment.base.exception.BusinessException;
import com.csun.dsms.comment.core.annotation.Authorization;
import com.csun.dsms.comment.core.annotation.CurrentUser;
import com.csun.dsms.comment.core.annotation.ValidateAnnotation;
import com.csun.dsms.comment.core.support.CsunMessageSource;
import com.csun.dsms.comment.core.utils.wrapper.WrapMapper;
import com.csun.dsms.comment.core.utils.wrapper.Wrapper;
import com.csun.dsms.model.domain.DsmsArea;
import com.csun.dsms.model.domain.DsmsStaff;
import com.csun.dsms.model.domain.DsmsUnit;
import com.csun.dsms.model.domain.DsmsUser;
import com.csun.dsms.model.dto.poor.PoorDto;
import com.csun.dsms.model.dto.staff.StaffDto;
import com.csun.dsms.model.dto.staff.StaffQueryDto;
import com.csun.dsms.model.dto.user.ModifyUserStatusDto;
import com.csun.dsms.model.dto.user.ResetPwdDto;
import com.csun.dsms.model.vo.staff.ApplyStaffDto;
import com.csun.dsms.model.vo.staff.ModifyStaffStatusDto;
import com.csun.dsms.model.vo.staff.StaffVo;
import com.csun.dsms.service.DsmsAreaService;
import com.csun.dsms.service.DsmsStaffService;
import com.csun.dsms.service.DsmsUnitService;
import com.csun.dsms.service.DsmsUserService;
import com.csun.dsms.utils.DateUtil;
import com.csun.dsms.utils.PublicUtil;
import com.csun.dsms.utils.ReadExcelUtils;
import com.csun.dsms.validator.DsmsStaffAddValidator;
import com.csun.dsms.validator.DsmsStaffEditValidator;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author chisj chisj@foxmail.com
 * @version 1.0.0
 * @date 2021-09-22 16:55
 * @description: 服务人员管理拦截器
 */

@Slf4j
@RestController
@RequestMapping("/staff")
public class DsmsStaffController {

    @Resource
    private CsunMessageSource csunMessageSource;
    @Resource
    private DsmsStaffService dsmsStaffService;
    @Resource
    private DsmsUserService dsmsUserService;
    @Resource
    private DsmsAreaService dsmsAreaService;
    @Resource
    private DsmsUnitService dsmsUnitService;

    /**
     * 查询服务公司所对应的网格列表
     *
     * @return the wrapper
     */
    @Authorization
    @PostMapping(value = "/queryAreaList")
    public Wrapper queryAreaList(@CurrentUser DsmsUser login) {

        // TODO 判断是否为服务公司管理员

        List<DsmsArea> areaList = dsmsAreaService.queryAreaList(login.getUnitId());

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), areaList);
    }

    /**
     * 查询服务人员列表.
     *
     * @param staffQueryDto the user query dto
     * @return the wrapper
     */
    @Authorization
    @PostMapping(value = "/queryListWithPage")
    public Wrapper queryUserListWithPage(@RequestBody StaffQueryDto staffQueryDto) {

        List<StaffVo> staffVoList = dsmsStaffService.queryListWithPage(staffQueryDto);

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), new PageInfo(staffVoList));
    }

    /**
     * 新增服务人员
     *
     * @param staffDto the staff dto
     * @return the wrapper
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/save")
    public Wrapper save(@CurrentUser DsmsUser login,
                        @Validated(DsmsStaffAddValidator.class) @RequestBody StaffDto staffDto,
                        BindingResult br) {

        Integer result = dsmsStaffService.save(staffDto, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null), result);
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 修改服务人员
     *
     * @param login    the login user
     * @param staffDto the staff dto
     * @return the wrapper.
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/edit")
    public Wrapper edit(@CurrentUser DsmsUser login,
                        @Validated(DsmsStaffEditValidator.class) @RequestBody StaffDto staffDto,
                        BindingResult br) {

        Integer result = dsmsStaffService.edit(staffDto, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 通过Id删除服务人员.
     *
     * @param staffId the user id
     * @return the wrapper
     */
    @Authorization
    @PostMapping(value = "/deleteById/{staffId}")
    public Wrapper deleteById(@PathVariable Long staffId) {

        Integer result = dsmsStaffService.deleteById(staffId);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 通过Id查询服务人员.
     *
     * @param staffId the staff id
     * @return the wrapper
     */
    @Authorization
    @PostMapping(value = "/showById/{staffId}")
    public Wrapper showById(@PathVariable Long staffId) {

        StaffVo staffVo = dsmsStaffService.showById(staffId);

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), staffVo);
    }

    /**
     * 重置服务人员密码
     *
     * @param login       the login user
     * @param resetPwdDto the reset password dto
     * @param br
     * @return wrapper
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/resetPwd")
    public Wrapper resetPwd(@CurrentUser DsmsUser login,
                            @Validated @RequestBody ResetPwdDto resetPwdDto,
                            BindingResult br) {

        Integer result = dsmsUserService.resetPwd(resetPwdDto, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 根据Id修改状态.
     *
     * @param modifyStaffStatusDto the modify staff status dto
     * @return the wrapper
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/modifyStatusById")
    public Wrapper<Integer> modifyStatusById(@CurrentUser DsmsUser login,
                                             @Valid @RequestBody ModifyStaffStatusDto modifyStaffStatusDto,
                                             BindingResult br) {

        DsmsStaff dsmsStaff = dsmsStaffService.selectByKey(modifyStaffStatusDto.getStaffId());
        if (PublicUtil.isEmpty(dsmsStaff)) {
            throw new BusinessException(ErrorCodeEnum.GB10051001);
        }

        DsmsUser dsmsUser = new DsmsUser();
        dsmsUser.setId(dsmsStaff.getUserId());
        dsmsUser.setStatus(modifyStaffStatusDto.getStatus());

        int result = dsmsUserService.modifyUserStatusById(dsmsUser, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 审核服务人员.
     *
     * @param applyStaffDto the apply staff dto
     * @return the wrapper
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/apply")
    public Wrapper apply(@CurrentUser DsmsUser login,
                         @Valid @RequestBody ApplyStaffDto applyStaffDto) {

        int result = dsmsStaffService.apply(applyStaffDto, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }


    @PostMapping(consumes = "multipart/form-data", value = "/importStaff")
    public Wrapper importStaff(HttpServletRequest request) throws Exception {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile("file");
        ReadExcelUtils excelReader = new ReadExcelUtils(file.getInputStream());
        Map<Integer, Map<Integer, Object>> map = excelReader.readExcelContent();
        log.info("服务人员上传,param:{}", map.toString());

        for (int i = 1; i <= map.size(); i++) {
            String unitName = (String) map.get(i).get(0);
            String areaName = (String) map.get(i).get(1);
            String name = (String) map.get(i).get(2);
            String idCard = (String) map.get(i).get(3);
            String serviceLength = (String) map.get(i).get(4);
            String sex = (String) map.get(i).get(5);
            String skill = (String) map.get(i).get(6);
            Date birthday = (Date) map.get(i).get(7);
            String mobileNo = (String) map.get(i).get(8);
            String loginPwd = (String) map.get(i).get(9);
            String remark = (String) map.get(i).get(10);

            StaffDto staffDto = new StaffDto();
            staffDto.setName(name);
            staffDto.setIdCard(idCard);
            staffDto.setServiceLength(Integer.valueOf(serviceLength.substring(0, serviceLength.indexOf("."))));
            staffDto.setSex(sex.equals("男") ? 1 : 0);
            staffDto.setSkill(skill);
            staffDto.setBirthday(DateUtil.dateToStr(birthday));
            staffDto.setMobileNo(mobileNo);
            staffDto.setLoginPwd(loginPwd);
            staffDto.setRemark(remark);

            Example example = new Example(DsmsUnit.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("name", unitName);
            List<DsmsUnit> dsmsUnits = dsmsUnitService.selectByExample(example);
            if (!CollectionUtils.isEmpty(dsmsUnits)) {
                staffDto.setUnitId(dsmsUnits.get(0).getId());
            }

            Example example1 = new Example(DsmsArea.class);
            Example.Criteria criteria1 = example1.createCriteria();
            criteria1.andEqualTo("name", areaName);
            List<DsmsArea> dsmsAreas = dsmsAreaService.selectByExample(example1);
            if (!CollectionUtils.isEmpty(dsmsAreas)) {
                staffDto.setAreaId(dsmsAreas.get(0).getId());
            }

            dsmsStaffService.save(staffDto, null);
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, "导入成功");
    }

    @GetMapping(value = "/exportModelStaff")
    public void exportModelStaff(HttpServletResponse response) throws Exception {
        ByteArrayOutputStream outputStream = null;
        String file_name = URLEncoder.encode("服务人员-", "UTF-8");
        //生成Excel
        outputStream = getModelDevGeomagneticExcelByte();
        byte[] byteArray = outputStream.toByteArray();
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Content-Disposition",
                "attachment;fileName=" + file_name + DateUtil.getNowTime() + ".xls");
        response.getOutputStream().write(byteArray);
    }


    private ByteArrayOutputStream getModelDevGeomagneticExcelByte() throws Exception {
        // 1.读取工作簿
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("excelModel/staff.xls");
        //获取模版
        HSSFWorkbook workbook = new HSSFWorkbook(is);
        //得到工作表
        HSSFSheet sheet = workbook.getSheetAt(0);
        //从第2行开始
        is.close();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        workbook.write(baos);
        if (workbook != null) {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return baos;
    }
}